﻿#region copyright
//<copyright>
// Copyright(C) 2012 TrackerRealm Corporation
// This file is part of the open source project - Jazz. http://jazz.codeplex.com
// 
// Jazzfire is open software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License (AGPL) as published by the Free Software Foundation, version 3 of the License.
// 
// Jazzfire is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Affero General Public License (AGPL) for more details.
// 
// You should have received a copy of the GNU General Public License along with Jetfire.  If not, see <http://www.gnu.org/licenses/>.
//
// REMOVAL OF THIS NOTICE IS VIOLATION OF THE COPYRIGHT. 
//</copyright>
#endregion
# region using
using System;
using System.Linq;
using System.Reflection;
using System.Collections.Generic;
using TrackerRealm.Jazz.Client;
# endregion

namespace TrackerRealm.Jazz.WindowsForm
{
    public static class jObjectExtensions
    {
        # region CanRead
        /// <summary>
        /// Returns true if the property can be read by the logged in user
        /// </summary>
        /// <param name="obj">jObject</param>
        /// <param name="pName">property Name</param>
        /// <returns></returns>
        public static bool CanRead(this jObject obj, string pName)
        {
            jPropertyInfo mi = obj.AllProperties().FirstOrDefault(m => m.Name == pName && m.CanRead);
            return (mi != null);
        }
        # endregion
        # region Read
        /// <summary>
        /// Gets object from the jObject for the property name
        /// </summary>
        /// <param name="obj">jObject</param>
        /// <param name="pName">property Name</param>
        /// <returns></returns>
        public static object Read(this jObject obj, string pName)
        {
            jPropertyInfo pi = obj.AllProperties().FirstOrDefault(m => m.Name == pName);
            if (pi == null)
                return String.Empty;
            if (!pi.CanRead)
                return String.Format("*** Cannot read {0} ***", pName);
            object o = pi.Read(obj);
            return o;
        }
        /// <summary>
        /// Gets object from the jObject for the property name
        /// </summary>
        /// <param name="obj">jObject</param>
        /// <param name="pName">property Name</param>
        /// <returns></returns>
        public static string ReadString(this jObject obj, string pName)
        {
            object o = obj.Read(pName);
            if (o == null)
                return String.Empty;
            if (o is String)
                return o.ToString();
            if (o is jState)
                return "Status: " + ((jState)o).Name;
            if (o is jProfileBase)
            {
                jProfileBase profile = (jProfileBase)o;
                if (profile.IsEmpty)
                    return "No one";
                return profile.Name;
            }
            if (o is jObject)
                return ((jObject)o).ToString();
            if (o is IEnumerable<jNameUnique>)
                return ((IEnumerable<jNameUnique>)o).ToReadableString("Name");
            if (o is IEnumerable<jAclItem>)
                return ((IEnumerable<jAclItem>)o).ToReadableString();
            return o.ToString();
        }
        # endregion
        # region List of PropertyInfo
        /// <summary>
        /// Gets the list of UI jPropertyInfo for the class
        /// </summary>
        /// <param name="obj">jObject</param>
        public static IEnumerable<jPropertyInfo> AllProperties(this jObject obj)
        {
            MemberInfo[] members = obj.GetType().GetMembers(BindingFlags.Public | BindingFlags.Instance | BindingFlags.FlattenHierarchy);
            return members.ToWrapper(obj).OfType<jPropertyInfo>().Where(m => m.CanRead);
        }
        /// <summary>
        /// Gets the list of properties for the Subclass
        /// </summary>
        /// <param name="obj">jObject</param>
        public static IEnumerable<jPropertyInfo> ClassProperties(this jObject obj)
        {
            return obj.GetType().GetMembers(BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.Instance).ToWrapper(obj).OfType<jPropertyInfo>();
        }
        /// <summary>
        /// Gets the list of methods for the Subclass
        /// </summary>
        /// <param name="obj">jObject</param>
        public static IEnumerable<jMethodInfo> ClassMethods(this jObject obj)
        {
            return obj.GetType().GetMembers(BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.Instance).ToWrapper(obj).OfType<jMethodInfo>();
        }
        # endregion
    }
}